local jinfan = fk.CreateSkill {
    name = "gai__jinfan",
    derived_piles = "mini__jinfan_ling",
  }
  
  Fk:loadTranslationTable{
    ["gai__jinfan"] = "锦帆",
    [":gai__jinfan"] = "准备阶段或弃牌阶段开始时，你可以将任意张手牌置于武将牌上，称为“铃”（每种花色限一张）。"..
    "你可以将“铃”如手牌般使用或打出，且无距离限制。当“铃”离开你的武将牌时，你从牌堆获得一张同花色的牌。",
  
    ["mini__jinfan_ling"] = "铃",
    ["#mini__jinfan-invoke"] = "锦帆：你可以将任意张手牌置为“铃”",
    ["#mini__jinfan"] = "锦帆：你可以使用或打出“铃”",
  
    ["$gai__jinfan1"] = "扬锦帆，劫四方，快意逍遥！",
    ["$gai__jinfan2"] = "铃声所至之处，再无安宁！",
  }
  
  jinfan:addEffect("viewas", {
    pattern = ".",
    prompt = "#mini__jinfan",
    expand_pile = function(self, player)
      return player:getPile("mini__jinfan_ling")
    end,
    card_filter = function(self, player, to_select, selected)
      if #selected == 0 and table.contains(player:getPile("mini__jinfan_ling"), to_select) then
        local card = Fk:getCardById(to_select)
        if Fk.currentResponsePattern == nil then
          return player:canUse(card) and not player:prohibitUse(card)
        else
          return Exppattern:Parse(Fk.currentResponsePattern):match(card)
        end
      end
    end,
    view_as = function(self, player, cards)
      if #cards ~= 1 then return end
      local card = Fk:getCardById(cards[1])
      local c = Fk:cloneCard(card.name, card.suit, card.number)
      c:addSubcards(cards)
      c.skillName = jinfan.name
      return c
    end,
    before_use = function (self, player, use)
      use.extraUse = false
    end,
    enabled_at_play = function(self, player)
      return #player:getPile("mini__jinfan_ling") > 0
    end,
    enabled_at_response = function(self, player, response)
      return #player:getPile("mini__jinfan_ling") > 0
    end,
    enabled_at_nullification = function (self, player, data)
      return table.find(player:getPile("mini__jinfan_ling"), function (id)
        return Fk:getCardById(id):matchVSPattern("nullification")
      end) ~= nil
    end,
  })
  
  jinfan:addEffect("targetmod", {
    bypass_distances = function (self, player, skill, card, to)
      return card and table.contains(card.skillNames, jinfan.name)
    end,
    bypass_times = function (self, player, skill, scope, card, to)
      return card and table.contains(card.skillNames, jinfan.name)
    end,
  })
  
  jinfan:addEffect(fk.EventPhaseStart, {
    anim_type = "special",
    can_trigger = function(self, event, target, player, data)
      return target == player and player:hasSkill(jinfan.name) and 
        (player.phase == Player.Start or player.phase == Player.Discard) and 
        not player:isKongcheng() and #player:getPile("mini__jinfan_ling") < 4
    end,
    on_cost = function (self, event, target, player, data)
      local success, dat = player.room:askToUseActiveSkill(player, {
        skill_name = "#mini__jinfan_active",
        prompt = "#mini__jinfan-invoke",
        cancelable = true,
      })
      if success and dat then
        event:setCostData(self, {cards = dat.cards})
        return true
      end
    end,
    on_use = function (self, event, target, player, data)
      player:addToPile("mini__jinfan_ling", event:getCostData(self).cards, true, jinfan.name)
    end,
  })
  
  jinfan:addEffect(fk.AfterCardsMove, {
    anim_type = "drawcard",
    can_trigger = function (self, event, target, player, data)
      if player:hasSkill(jinfan.name) then
        for _, move in ipairs(data) do
          if move.from == player then
            for _, info in ipairs(move.moveInfo) do
              if info.fromSpecialName == "mini__jinfan_ling" then
                return true
              end
            end
          end
        end
      end
    end,
    on_cost = Util.TrueFunc,
    on_use = function (self, event, target, player, data)
      local room = player.room
      local suits = {}
      for _, move in ipairs(data) do
        if move.from == player then
          for _, info in ipairs(move.moveInfo) do
            if info.fromSpecialName == "mini__jinfan_ling" then
              table.insertIfNeed(suits, Fk:getCardById(info.cardId):getSuitString())
            end
          end
        end
      end
      for _, suit in ipairs(suits) do
        if player.dead then return end
        local cards = room:getCardsFromPileByRule(".|.|"..suit)
        if #cards > 0 then
          room:obtainCard(player, cards[1], false, fk.ReasonJustMove, player, jinfan.name)
        end
      end
    end,
  })
  
  return jinfan